﻿Imports DevComponents.DotNetBar.SuperGrid

Public Class FILTERCLASSGRID 'คลาสหนูน้อยอะไรหว่า version กริ๊ดๆๆ
    Private gridX As SuperGridControl
    Private cellX As DevComponents.DotNetBar.SuperGrid.GridCell

    Dim connect As CONDB = CONDB.NewConnection()
    Private dgvSearch As New DataGridView
    Private dtSearch As DataTable
    Private colWidth() As String
    Private colText() As String
    Private colVisible() As String
    Private colFilter() As String
    Private showInColumnName As New List(Of String)
    Private IsShowInDown As Boolean = True
    Private IsShowBorder As Boolean = False
    Private tagIndex As Integer = 0
    Private textIndex As Integer = 1
    Private searchHeight As Integer = 0
    Private sql As String = ""

    Public Overridable Property SetSql As String
        Get
            Return sql
        End Get
        Set(value As String)
            Me.sql = value
            Call getData()
        End Set
    End Property

    Public Overridable WriteOnly Property SetColText As String
        Set(value As String)
            colText = value.Split(",")
        End Set
    End Property

    Public Overridable WriteOnly Property SetColWidth As String
        Set(value As String)
            colWidth = value.Split(",")
        End Set
    End Property

    Public Overridable WriteOnly Property SetColVisible As String
        Set(value As String)
            colVisible = value.Split(",")
        End Set
    End Property

    Public Overridable WriteOnly Property SetShowInColumnName As String
        Set(value As String)
            showInColumnName.Add(value)
        End Set
    End Property

    Public Overridable WriteOnly Property SetColFilter As String
        Set(value As String)
            colFilter = value.Split(",")
        End Set
    End Property

    Public Overridable WriteOnly Property SetShowInDown As Boolean
        Set(value As Boolean)
            IsShowInDown = value
        End Set
    End Property

    Public Overridable WriteOnly Property SetShowBorder As Boolean
        Set(value As Boolean)
            IsShowBorder = value
            If IsShowBorder = False Then
                dgvSearch.BorderStyle = BorderStyle.None
            Else
                dgvSearch.BorderStyle = BorderStyle.FixedSingle
            End If
        End Set
    End Property

    Public Overridable WriteOnly Property SetTagIndex As Integer
        Set(value As Integer)
            tagIndex = value
        End Set
    End Property

    Public Overridable WriteOnly Property SetTextIndex As Integer
        Set(value As Integer)
            textIndex = value
        End Set
    End Property

    Public Sub New(grid As SuperGridControl, sql As String)
        Begin(grid, sql)
    End Sub

    Public Sub New(grid As SuperGridControl, sql As String, ColumnsText As String)
        Begin(grid, sql)
        colText = ColumnsText.Split(",")
    End Sub

    Public Sub New(grid As SuperGridControl, sql As String, ColumnsText As String, ColumnsWidth As String)
        Begin(grid, sql)
        colText = ColumnsText.Split(",")
        colWidth = ColumnsWidth.Split(",")
    End Sub

    Public Sub New(grid As SuperGridControl, sql As String, ColumnsText As String, ColumnsWidth As String, ColumnsVisible As String)
        Begin(grid, sql)
        colText = ColumnsText.Split(",")
        colWidth = ColumnsWidth.Split(",")
        colVisible = ColumnsVisible.Split(",")
    End Sub

    Public Sub New(grid As SuperGridControl, sql As String, ColumnsText As String, ColumnsWidth As String, ColumnsVisible As String, ColumnsFilter As String)
        Begin(grid, sql)
        colText = ColumnsText.Split(",")
        colWidth = ColumnsWidth.Split(",")
        colVisible = ColumnsVisible.Split(",")
        colFilter = ColumnsFilter.Split(",")
    End Sub


    Private Sub Begin(grid As SuperGridControl, sqlX As String)
        sql = sqlX
        gridX = grid
        Me.searchHeight = 200
        With dgvSearch
            .ReadOnly = True
            .Height = Me.searchHeight
            .RowHeadersDefaultCellStyle.BackColor = System.Drawing.Color.LightBlue
            .BackgroundColor = System.Drawing.Color.White
            .AlternatingRowsDefaultCellStyle.BackColor = Color.AliceBlue
            .RowHeadersVisible = False
            .AllowUserToAddRows = False
            .DefaultCellStyle.WrapMode = DataGridViewTriState.NotSet
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .BorderStyle = BorderStyle.None
            .BackgroundColor = Color.White
            .GridColor = System.Drawing.Color.FromArgb(255, 215, 228, 242)
            .EnableHeadersVisualStyles = False
            .ColumnHeadersDefaultCellStyle.BackColor = System.Drawing.Color.FromArgb(255, 185, 209, 234)
            .Name = "dgvSearch"
            .Parent = grid '.FindForm()
            .Visible = False
            .AutoSizeRowsMode = DataGridViewAutoSizeRowsMode.DisplayedCells
            .RowsDefaultCellStyle.WrapMode = DataGridViewTriState.True
        End With
        AddHandler dgvSearch.CellMouseClick, AddressOf Me.dgvSearchClick
        AddHandler dgvSearch.KeyDown, AddressOf Me.dgvSearchKey
        AddHandler grid.EditorValueChanged, AddressOf Me.gridEditorValueChanged
        AddHandler grid.KeyUp, AddressOf Me.gridKeyUp
        AddHandler grid.KeyDown, AddressOf Me.gridKeyDown
        AddHandler grid.KeyPress, AddressOf Me.gridKeyPress
        AddHandler grid.CellClick, AddressOf Me.gridMouseClick
        'AddHandler grid.Parent.MouseClick, AddressOf Me.parentMouseClick
        'AddHandler dgvSearch.Parent.MouseClick, AddressOf Me.parentMouseClick
        Call RecurseControlsAddHandler(dgvSearch.Parent.FindForm())
        Call getData()
    End Sub

    Private Sub RecurseControlsAddHandler(ByVal ctrX As Control)
        If ctrX.HasChildren Then
            For Each c As Control In ctrX.Controls
                If TypeOf (c) Is Panel Then
                    Dim ctl As Panel
                    ctl = CType(c, Panel)
                    AddHandler ctl.MouseClick, AddressOf Me.parentMouseClick
                ElseIf TypeOf (c) Is GroupBox Then
                    Dim ctl As GroupBox
                    ctl = CType(c, GroupBox)
                    AddHandler ctl.MouseClick, AddressOf Me.parentMouseClick
                ElseIf TypeOf (c) Is PictureBox Then
                    Dim ctl As PictureBox
                    ctl = CType(c, PictureBox)
                    AddHandler ctl.MouseClick, AddressOf Me.parentMouseClick
                ElseIf TypeOf (c) Is DataGridView And c.Name.Trim <> "dgvSearch" Then
                    Dim ctl As DataGridView
                    ctl = CType(c, DataGridView)
                    AddHandler ctl.MouseClick, AddressOf Me.parentMouseClick
                ElseIf TypeOf (c) Is DevComponents.DotNetBar.SuperGrid.SuperGridControl Then
                    Dim ctl As DevComponents.DotNetBar.SuperGrid.SuperGridControl
                    ctl = CType(c, DevComponents.DotNetBar.SuperGrid.SuperGridControl)
                    AddHandler ctl.MouseClick, AddressOf Me.parentMouseClick
                ElseIf TypeOf (c) Is DevComponents.DotNetBar.Controls.DataGridViewX Then
                    Dim ctl As DevComponents.DotNetBar.Controls.DataGridViewX
                    ctl = CType(c, DevComponents.DotNetBar.Controls.DataGridViewX)
                    AddHandler ctl.MouseEnter, AddressOf Me.parentMouseClick
                ElseIf TypeOf (c) Is DevComponents.DotNetBar.PanelEx Then
                    Dim ctl As DevComponents.DotNetBar.PanelEx
                    ctl = CType(c, DevComponents.DotNetBar.PanelEx)
                    AddHandler ctl.MouseClick, AddressOf Me.parentMouseClick
                ElseIf TypeOf (c) Is DevComponents.DotNetBar.TabControl Then
                    Dim ctl As DevComponents.DotNetBar.TabControl
                    ctl = CType(c, DevComponents.DotNetBar.TabControl)
                    AddHandler ctl.MouseClick, AddressOf Me.parentMouseClick
                    AddHandler ctl.SelectedTabChanged, AddressOf Me.parentSelectTabChange
                End If
                RecurseControlsAddHandler(c)
            Next c
        End If
    End Sub

    Private Sub getData()
        Dim connect As CONDB = CONDB.NewConnection()
        dtSearch = New DataTable()
        dtSearch = connect.GetTable(sql)
        connect.Dispose()
    End Sub

    Private Sub ColumnsText()
        If colText Is Nothing Then
            Return
        End If
        For i As Integer = 0 To colText.Length - 1
            dgvSearch.Columns(i).HeaderText = colText(i)
        Next
    End Sub

    Private Sub ColumnsWidth()
        If colWidth Is Nothing Then
            Return
        End If
        For i As Integer = 0 To colWidth.Length - 1
            dgvSearch.Columns(i).Width = colWidth(i)
        Next
    End Sub

    Private Sub ColumnsVisible()
        If colWidth Is Nothing Then
            Return
        End If

        For i As Integer = 0 To colWidth.Length - 1
            dgvSearch.Columns(i).Width = colWidth(i)
        Next

        For i As Integer = 0 To colVisible.Length - 1
            If colVisible(i).Trim = "0" Then
                dgvSearch.Columns(i).Visible = False
            Else
                dgvSearch.Columns(i).Visible = True
                dgvSearch.Columns(i).Width = cellX.Size.Width - 20
            End If
        Next

    End Sub



    Private Sub dgvSearchClick(ByVal sender As Object, ByVal e As DataGridViewCellMouseEventArgs)
        If e.RowIndex = -1 Then
            Return
        End If
        cellX.Tag = dgvSearch.Rows(e.RowIndex).Cells(tagIndex).Value.ToString
        cellX.Value = dgvSearch.Rows(e.RowIndex).Cells(textIndex).Value.ToString

        dgvSearch.DataSource = Nothing
        dgvSearch.Visible = False
        gridX.Focus()
    End Sub


    Private Sub dgvSearchKey(ByVal sender As Object, ByVal e As KeyEventArgs)
        If e.KeyCode = Keys.Enter Then
            For i As Integer = 0 To dgvSearch.Rows.Count - 1
                If dgvSearch.Rows(i).Cells(1).Selected = True Then
                    cellX.Tag = dgvSearch.Rows(i).Cells(tagIndex).Value.ToString
                    cellX.Value = dgvSearch.Rows(i).Cells(textIndex).Value.ToString
                    dgvSearch.DataSource = Nothing
                    dgvSearch.Visible = False
                    gridX.Focus()
                    Return
                End If
            Next i
        ElseIf e.KeyCode = Keys.Escape Then
            dgvSearch.DataSource = Nothing
            dgvSearch.Visible = False
        End If
    End Sub

    Private Sub gridEditorValueChanged(sender As Object, e As GridEditEventArgs)
        If IsFilterColumn() = True Then
            cellX.Tag = Nothing
            FilterGrid(e.EditControl.EditorValue.ToString.Trim)
        End If
    End Sub


    Private Sub gridKeyPress(sender As Object, e As KeyPressEventArgs)
        If e.KeyChar.ToString.Trim = "'" Then
            e.KeyChar = ""
        End If
    End Sub

    Private Sub gridKeyDown(sender As Object, e As KeyEventArgs)
        'ctl.Tag = Nothing
        If e.KeyCode = Keys.Enter And IsFilterColumn() = True Then
            If gridX.Focused Then
                For i As Integer = 0 To dgvSearch.Rows.Count - 1
                    If dgvSearch.Rows(i).Cells(1).Selected = True Then
                        cellX.Tag = dgvSearch.Rows(i).Cells(tagIndex).Value.ToString
                        cellX.Value = dgvSearch.Rows(i).Cells(textIndex).Value.ToString
                        dgvSearch.DataSource = Nothing
                        dgvSearch.Visible = False
                        Return
                    End If
                Next i
            End If
        End If
    End Sub


    Private Sub gridKeyUp(sender As Object, e As KeyEventArgs)
        If IsFilterColumn() = True Then
            If e.KeyCode = Keys.Down Then
                e.Handled = False
                dgvSearch.Focus()
            ElseIf e.KeyCode = Keys.Enter Then
                If dgvSearch.Rows.Count = 1 Then
                    cellX.Tag = dgvSearch.Rows(0).Cells(tagIndex).Value.ToString
                    cellX.Value = dgvSearch.Rows(0).Cells(textIndex).Value.ToString
                    dgvSearch.DataSource = Nothing
                    dgvSearch.Visible = False
                    Return
                End If
            ElseIf e.KeyCode = Keys.Escape Then
                dgvSearch.DataSource = Nothing
                dgvSearch.Visible = False
            End If
        End If
    End Sub

    Private Sub parentMouseClick(sender As Object, e As MouseEventArgs)
        dgvSearch.DataSource = Nothing
        dgvSearch.Visible = False
    End Sub

    Private Sub parentSelectTabChange(sender As Object, e As DevComponents.DotNetBar.TabStripTabChangedEventArgs)
        dgvSearch.DataSource = Nothing
        dgvSearch.Visible = False
    End Sub

    Private Sub gridMouseClick(sender As Object, e As DevComponents.DotNetBar.SuperGrid.GridCellClickEventArgs)
        cellX = e.GridCell
        'If showInColumnName IsNot Nothing Then
        '    For i As Integer = 0 To showInColumnName.Count - 1
        '        If e.GridCell.GridColumn.Name.Trim = showInColumnName.Item(i).Trim Then
        '            i = showInColumnName.Count
        '        ElseIf i = showInColumnName.Count - 1 Then
        '            Return
        '        End If
        '    Next i

        If IsFilterColumn() = False Then
            Return
        End If

        If e.GridCell.InfoText Is Nothing Then
            If e.GridCell.Value Is DBNull.Value Then
                e.GridCell.InfoText = ""
            Else
                e.GridCell.InfoText = e.GridCell.Value 'เก็บค่าเดิม
            End If
        End If

        If dgvSearch.Visible = False Then
            '    hideSearchControl()
            If dgvSearch.DataSource Is Nothing Then
                'cellX = e.GridCell
                With dgvSearch
                    .DataSource = dtSearch
                    'calSearchHeight()
                    .Location = New Point(e.GridCell.LocationRelative.X, e.GridCell.LocationRelative.Y + e.GridPanel.DefaultRowHeight)
                    .Width = e.GridCell.GridColumn.Size.Width
                    .Visible = True
                    .BringToFront()
                End With
                ColumnsText()
                ColumnsWidth()
                ColumnsVisible()

            Else
                dgvSearch.Visible = True
            End If
            If e.GridCell.Value IsNot Nothing Then
                FilterGrid(e.GridCell.Value.ToString.Trim)
            Else
                FilterGrid("")
            End If
            'MsgBox("Y:" & e.GridCell.LocationRelative.Y + e.GridPanel.DefaultRowHeight + dgvSearch.Height & vbCrLf & "gridHeight:" & gridX.Height)
            ShowUpOrDown()
        Else
            dgvSearch.DataSource = Nothing
            dgvSearch.Visible = False
        End If
        'End If
    End Sub

    Private Function IsFilterColumn() As Boolean
        If showInColumnName IsNot Nothing And cellX IsNot Nothing Then
            For i As Integer = 0 To showInColumnName.Count - 1
                If cellX.GridColumn.Name.Trim = showInColumnName.Item(i).Trim Then
                    Return True
                ElseIf i = showInColumnName.Count - 1 Then
                    Return False
                End If
            Next i
            Return False
        Else
            Return False
        End If
    End Function

    Private Sub ShowUpOrDown()
        'MsgBox("Y:" & cellX.LocationRelative.Y + cellX.GridPanel.DefaultRowHeight + dgvSearch.Height & vbCrLf & "gridHeight:" & gridX.Height)
        If cellX.LocationRelative.Y + cellX.GridPanel.DefaultRowHeight + dgvSearch.Height > gridX.Height Or dgvSearch.Location.Y < cellX.LocationRelative.Y Then
            dgvSearch.Location = New Point(dgvSearch.Location.X, cellX.LocationRelative.Y - dgvSearch.Height)
        End If

    End Sub

    Private Sub calSearchHeight()
        If dgvSearch.Rows.Count > 0 Then
            dgvSearch.Height = (dgvSearch.Rows.Count * dgvSearch.Rows(dgvSearch.Rows.Count - 1).Height) + 40
        Else
            dgvSearch.Height = (dgvSearch.Rows.Count * 0) + 40
        End If
        If dgvSearch.Height > Me.searchHeight Then
            dgvSearch.Height = Me.searchHeight
        End If
    End Sub

    Private Sub FilterGrid(str As String)
        Try

            Dim dv As New DataView
            dv = dtSearch.DefaultView
            dgvSearch.Visible = True
            Dim txtFilter As String = ""
            If colFilter Is Nothing Then
                For i As Integer = 0 To dtSearch.Columns.Count - 1
                    txtFilter += "CONVERT(" + dtSearch.Columns(i).ColumnName + ", System.String) LIKE '%" & str & "%' "
                    txtFilter += "OR "
                Next i
            Else
                For i As Integer = 0 To colFilter.Length - 1
                    If colFilter(i).Trim = "1" Then
                        txtFilter += "CONVERT(" + dtSearch.Columns(i).ColumnName + ", System.String) LIKE '%" & str & "%' "
                        txtFilter += "OR "
                    End If
                Next i
            End If
            txtFilter = txtFilter.Remove(txtFilter.Length - 3, 3)
            dv.RowFilter = txtFilter
            With dgvSearch
                .DataSource = dv.ToTable
            End With
            calSearchHeight()
            'calLocation()
            'ColumnsWidth()
            ColumnsVisible()
            ShowUpOrDown()
        Catch ex As Exception
            MsgBox("error : " & ex.Message)
        End Try
    End Sub

    Private Sub hideSearchControl()
        For Each c As Control In dgvSearch.Parent.Controls
            If c.Name = "dgvSearch" Then
                c.Visible = False
            End If
        Next
    End Sub

End Class
